1 module hip.systems.gamepads.psv;
2 import hip.systems.gamepad;
3 
4 version(PSVita){}
5 else
6 {
7     alias HipPSVGamepad = HipNullGamepad;
8 }
9 version(PSVita):
10 
11 /** Enumeration for the digital controller buttons.
12  * @note - L1/R1/L3/R3 only can bind using ::sceCtrlPeekBufferPositiveExt2 and ::sceCtrlReadBufferPositiveExt2
13  * @note - Vita's L Trigger and R Trigger are mapped to L1 and R1 when using ::sceCtrlPeekBufferPositiveExt2 and ::sceCtrlReadBufferPositiveExt2
14  */
15 enum PsvButtons : uint
16 {
17 	SELECT      = 0x00000001,       //!< Select button.
18 	L3          = 0x00000002,       //!< L3 button.
19 	R3          = 0x00000004,       //!< R3 button.
20 	START       = 0x00000008,       //!< Start button.
21 	UP          = 0x00000010,       //!< Up D-Pad button.
22 	RIGHT       = 0x00000020,       //!< Right D-Pad button.
23 	DOWN        = 0x00000040,       //!< Down D-Pad button.
24 	LEFT        = 0x00000080,       //!< Left D-Pad button.
25 	LTRIGGER    = 0x00000100,       //!< Left trigger.
26 	L2          = LTRIGGER,     //!< L2 button.
27 	RTRIGGER    = 0x00000200,       //!< Right trigger.
28 	R2          = RTRIGGER,     //!< R2 button.
29 	L1          = 0x00000400,       //!< L1 button.
30 	R1          = 0x00000800,       //!< R1 button.
31 	TRIANGLE    = 0x00001000,       //!< Triangle button.
32 	CIRCLE      = 0x00002000,       //!< Circle button.
33 	CROSS       = 0x00004000,       //!< Cross button.
34 	SQUARE      = 0x00008000,       //!< Square button.
35 }
36 
37 pragma(inline, true) bool isPSVButtonPressed(uint btns, PsvButtons btn){return (btns & btn) == btn;}
38 extern(C) void hipVitaPollGamepad(HipInputPSVGamepadState* state);
39 
40 struct HipInputPSVGamepadState
41 {
42     uint buttons;
43     ubyte[2] leftAnalog; ///X, Y
44     ubyte[2] rightAnalog; ///X, Y
45 }
46 class HipPSVGamepad : IHipGamepadImpl
47 {
48 
49     void poll(HipGamepad pad)
50     {
51         HipInputPSVGamepadState state;
52         hipVitaPollGamepad(&state);
53 
54         uint b = state.buttons;
55         with(pad)
56         {
57             enum center = 128;
58             enum div = 128;
59 
60             float lx = cast(float)state.leftAnalog[0];
61             float ly = cast(float)state.leftAnalog[1];
62 
63             float rx = cast(float)state.rightAnalog[0];
64             float ry = cast(float)state.rightAnalog[1];
65 
66             
67             setAnalog(HipGamepadAnalogs.leftStick, [
68                 (lx - center) / div,
69                 (ly - center) / div, 
70                 1
71             ]);
72 
73             setAnalog(HipGamepadAnalogs.rightStick, [
74                 (rx - center) / div,
75                 (ry - center) / div, 
76                 1
77             ]);
78 
79             leftTrigger = 0; rightTrigger = 0;
80 
81 
82             setButtonPressed(HipGamepadButton.psTriangle, isPSVButtonPressed(b, PsvButtons.TRIANGLE));
83             setButtonPressed(HipGamepadButton.psSquare, isPSVButtonPressed(b, PsvButtons.SQUARE));
84             setButtonPressed(HipGamepadButton.psCross, isPSVButtonPressed(b, PsvButtons.CROSS));
85             setButtonPressed(HipGamepadButton.psCircle, isPSVButtonPressed(b, PsvButtons.CIRCLE));
86 
87 
88             setButtonPressed(HipGamepadButton.dPadUp, isPSVButtonPressed(b, PsvButtons.UP));
89             setButtonPressed(HipGamepadButton.dPadLeft, isPSVButtonPressed(b, PsvButtons.LEFT));
90             setButtonPressed(HipGamepadButton.dPadDown, isPSVButtonPressed(b, PsvButtons.DOWN));
91             setButtonPressed(HipGamepadButton.dPadRight, isPSVButtonPressed(b, PsvButtons.RIGHT));
92 
93             setButtonPressed(HipGamepadButton.select, isPSVButtonPressed(b, PsvButtons.SELECT));
94             setButtonPressed(HipGamepadButton.start, isPSVButtonPressed(b, PsvButtons.START));
95 
96             setButtonPressed(HipGamepadButton.left1, isPSVButtonPressed(b, PsvButtons.LTRIGGER));
97             setButtonPressed(HipGamepadButton.right1, isPSVButtonPressed(b, PsvButtons.RTRIGGER));
98 
99 
100         }
101 
102     }
103 
104     void setVibrating(ubyte id, double leftMotor, double rightMotor, double leftTrigger, double rightTrigger){}
105     bool isWireless(ubyte id){return false;}
106     HipGamepadBatteryStatus getBatteryStatus(ubyte id)
107     {
108         return HipGamepadBatteryStatus.init; // TODO: implement
109     }
110 }